class Solution
{
public:
    int kthLargestValue(vector<vector<int>> &matrix, int k)
    {
        priority_queue<int, vector<int>, greater<int>> q;
        auto refreshKMax = [&](int num)
        {
            if (q.size() < k)
            {
                q.push(num);
            }
            else
            {
                if (num > q.top())
                {
                    q.pop();
                    q.push(num);
                }
            }
        };
        int m = matrix.size();
        int n = matrix[0].size();
        vector<int> lastRowXorPrefix(n, 0);
        vector<int> thisRowXorPrefix(n, 0);
        for (int i = 0; i < m; ++i)
        {
            thisRowXorPrefix[0] = matrix[i][0] ^ lastRowXorPrefix[0];
            refreshKMax(thisRowXorPrefix[0]);
            for (int j = 1; j < n; ++j)
            {
                thisRowXorPrefix[j] = matrix[i][j] ^ lastRowXorPrefix[j] ^ lastRowXorPrefix[j - 1] ^ thisRowXorPrefix[j - 1];
                refreshKMax(thisRowXorPrefix[j]);
            }
            thisRowXorPrefix.swap(lastRowXorPrefix);
        }
        return q.top();
    }
};